package com.example.blog.service.AllToAll;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

@Service
public class WordToPdfService {

    /**
     * 将Word文档转换为PDF文件
     * @param wordPath Word文件路径
     * @param pdfPath 生成的PDF文件路径
     */
    public void convertWordToPdf(String wordPath, String pdfPath) {
        try (InputStream docFile = Files.newInputStream(Paths.get(wordPath));
             XWPFDocument document = new XWPFDocument(docFile);
             PDDocument pdfDocument = new PDDocument()) {

            PDPage page = new PDPage();
            pdfDocument.addPage(page);

            PDPageContentStream contentStream = new PDPageContentStream(pdfDocument, page);

            // 加载支持中文的字体
            File fontFile = new File("src/main/resources/NotoSansSC-VariableFont_wght.ttf");
            if (!fontFile.exists()) {
                throw new RuntimeException("Font file not found: " + fontFile.getAbsolutePath());
            }
            PDType0Font font = PDType0Font.load(pdfDocument, fontFile);

            float yPosition = page.getMediaBox().getHeight() - 50;
            float margin = 50;
            float width = page.getMediaBox().getWidth() - 2 * margin;
            float lineHeight = 15;

            // 处理段落
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                yPosition = processParagraph(contentStream, font, paragraph, margin, width, yPosition, lineHeight);
                yPosition -= lineHeight;
            }

            // 处理表格
            for (XWPFTable table : document.getTables()) {
                yPosition -= lineHeight;
                yPosition = processTable(contentStream, font, table, margin, width, yPosition, lineHeight);
                yPosition -= lineHeight;
            }

            contentStream.close();
            pdfDocument.save(pdfPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private float processParagraph(PDPageContentStream contentStream, PDType0Font font, XWPFParagraph paragraph, float margin, float width, float yPosition, float lineHeight) throws Exception {
        contentStream.beginText();
        contentStream.setFont(font, 12);
        contentStream.newLineAtOffset(margin, yPosition);
        contentStream.setLeading(lineHeight);

        String text = paragraph.getText();
        contentStream.showText(text);

        contentStream.endText();
        return yPosition - lineHeight;
    }

    private float processTable(PDPageContentStream contentStream, PDType0Font font, XWPFTable table, float margin, float width, float yPosition, float lineHeight) throws Exception {
        float tableTopY = yPosition;

        for (XWPFTableRow row : table.getRows()) {
            List<XWPFTableCell> cells = row.getTableCells();
            float cellWidth = width / cells.size();
            float cellMargin = 5;

            for (int i = 0; i < cells.size(); i++) {
                XWPFTableCell cell = cells.get(i);
                contentStream.beginText();
                contentStream.setFont(font, 12);
                contentStream.newLineAtOffset(margin + i * cellWidth + cellMargin, yPosition);
                contentStream.setLeading(lineHeight);

                for (XWPFParagraph paragraph : cell.getParagraphs()) {
                    List<XWPFRun> runs = paragraph.getRuns();
                    for (XWPFRun run : runs) {
                        String text = run.text();
                        contentStream.showText(text);
                    }
                }

                contentStream.endText();
                // Draw cell border
                contentStream.moveTo(margin + i * cellWidth, yPosition);
                contentStream.lineTo(margin + (i + 1) * cellWidth, yPosition);
                contentStream.stroke();
            }
            yPosition -= lineHeight;
        }

        // Draw table borders
        for (int i = 0; i <= table.getRows().size(); i++) {
            contentStream.moveTo(margin, tableTopY - i * lineHeight);
            contentStream.lineTo(margin + width, tableTopY - i * lineHeight);
            contentStream.stroke();
        }
        for (int i = 0; i <= table.getRow(0).getTableCells().size(); i++) {
            contentStream.moveTo(margin + i * (width / table.getRow(0).getTableCells().size()), tableTopY);
            contentStream.lineTo(margin + i * (width / table.getRow(0).getTableCells().size()), tableTopY - table.getRows().size() * lineHeight);
            contentStream.stroke();
        }

        return yPosition;
    }
}




